#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include"loop_queue.h"
#include"handleEpollEvent.h"
#include <unistd.h>

#define TIME_OUT 30
#define MAX_CONNECTION 100



FdMapping fd_mapping; // 全局映射变量

// 初始化映射结构
void initFdMapping() {
    for (int i = 0; i < TIME_OUT; i++) {
        for (int j = 0; j < MAX_CONNECTION; j++) {
            fd_mapping.netfd_to_slot[i][j] = -1;
        }
    }
    for (int i = 0; i < MAX_CONNECTION; i++) {
        fd_mapping.netfd_to_index[i] = -1;
        fd_mapping.index_to_netfd[i] = -1;
    }
    fd_mapping.next_index = 0;
}

// 原有初始化函数保持不变，只添加映射初始化
LoopQueue_t* LoopQueueEpollInit() {
    // 初始化映射结构
    initFdMapping();
    
    // 原有时间轮盘初始化逻辑
    LoopQueue_t *time_queue = createLoopQueue(TIME_OUT);
    for (int i = 0; i < TIME_OUT; i++) {
        int *time = (int *)calloc(MAX_CONNECTION, sizeof(int));
        for (int j = 0; j < MAX_CONNECTION; j++) {
            time[j] = -1;
        }
        enqueueLoop(time_queue, time);
    }
    return time_queue;
}

// 修改后的handleNewClient函数，保持原有逻辑但添加映射
int handleNewClient(LoopQueue_t *time_queue, int netfd) {
    time_t current_time = time(NULL);
    int time_seconds = (int)current_time % TIME_OUT;
    
    // 查找空闲位置（原有逻辑）
    for (int j = 0; j < MAX_CONNECTION; j++) {
        if (time_queue->array[time_seconds][j] == -1) {
            // 1. 在时间轮盘中存储netfd（原有逻辑不变）
            time_queue->array[time_seconds][j] = netfd;
            
            // 2. 建立映射关系（新增部分）
            if (fd_mapping.next_index < MAX_CONNECTION) {
                int current_index = fd_mapping.next_index++;
                
                // 记录netfd到全局索引的映射
                fd_mapping.netfd_to_index[netfd] = current_index;
                fd_mapping.index_to_netfd[current_index] = netfd;
                
                // 记录netfd在时间轮盘中的位置
                fd_mapping.netfd_to_slot[time_seconds][current_index] = j;
            }
            
            break;
        }
    }
    return 0;
}

// 新增的查找函数：根据netfd找到其在二维数组中的位置
void findPositionByNetfd(int netfd, int *time_slot, int *slot_index) {
    *time_slot = -1;
    *slot_index = -1;
    
    // 1. 先通过netfd找到全局索引
    int global_index = fd_mapping.netfd_to_index[netfd];
    if (global_index == -1) return;
    
    // 2. 遍历所有时间槽查找这个索引
    for (int i = 0; i < TIME_OUT; i++) {
        for (int j = 0; j < MAX_CONNECTION; j++) {
            if (fd_mapping.netfd_to_slot[i][global_index] == j) {
                *time_slot = i;
                *slot_index = j;
                return;
            }
        }
    }
}

// 更新netfd的位置，当有客户端连接时调用
int updateNetfdPosition(LoopQueue_t *time_queue, int netfd) {
    // 获取当前时间对应的时间槽
    time_t current_time = time(NULL);
    int time_seconds = (int)current_time % TIME_OUT;

    // 检查该netfd是否已存在
    int global_index = fd_mapping.netfd_to_index[netfd];
    if (global_index != -1) {
        // 如果已存在，需要先从旧位置移除
        int old_time_slot = -1;
        int old_slot_index = -1;

        // 查找旧位置
        for (int i = 0; i < TIME_OUT; i++) {
            if (fd_mapping.netfd_to_slot[i][global_index] != -1) {
                old_time_slot = i;
                old_slot_index = fd_mapping.netfd_to_slot[i][global_index];
                // 清除旧位置的映射
                fd_mapping.netfd_to_slot[i][global_index] = -1;
                break;
            }
        }

        // 清除时间轮盘中的旧记录
        if (old_time_slot != -1) {
            time_queue->array[old_time_slot][old_slot_index] = -1;
        }
    } else {
        // 如果是新连接，分配新的全局索引
        if (fd_mapping.next_index >= MAX_CONNECTION) {
            printf("错误：连接数已达到最大值\n");
            return -1;
        }
        global_index = fd_mapping.next_index++;
        fd_mapping.netfd_to_index[netfd] = global_index;
        fd_mapping.index_to_netfd[global_index] = netfd;
    }
    // 查找新时间槽中的空闲位置
    int new_slot_index = -1;
    for (int j = 0; j < MAX_CONNECTION; j++) {
        if (time_queue->array[time_seconds][j] == -1) {
            new_slot_index = j;
            break;
        }
    }
    if (new_slot_index == -1) {
        printf("错误：时间槽 %d 已满\n", time_seconds);
        return -1;
    }
    // 更新时间轮盘和映射
    time_queue->array[time_seconds][new_slot_index] = netfd;
    fd_mapping.netfd_to_slot[time_seconds][global_index] = new_slot_index;

    return 0;
}


// 每隔30s检查时间轮盘上的连接，踢掉超时的连接
void timecheck(LoopQueue_t *time_queue) {
    time_t current_time = time(NULL);
    int current_slot = (int)current_time % TIME_OUT;
    
    // 遍历当前时间槽中的所有连接
    for (int j = 0; j < MAX_CONNECTION; j++) {
        int netfd = time_queue->array[current_slot][j];
        if (netfd != -1) {
            int global_index = fd_mapping.netfd_to_index[netfd];
            if (global_index != -1) {
                // 检查该连接是否存在于其他时间槽中
                int found = 0;
                for (int i = 0; i < TIME_OUT; i++) {
                    if (i == current_slot) continue; // 跳过当前时间槽
                    if (fd_mapping.netfd_to_slot[i][global_index] != -1) {
                        found = 1;
                        break;
                    }
                }
                
                if (!found) {
                    // 连接不存在于其他时间槽中，说明超时
                    printf("连接 %d 超时，已踢掉\n", netfd);
                    
                    // 关闭网络连接（实际应用中需要这一步）
                    close(netfd);
                    
                    // 清除映射
                    fd_mapping.netfd_to_index[netfd] = -1;
                    fd_mapping.index_to_netfd[global_index] = -1;
                    
                    // 清除时间轮盘中的记录
                    time_queue->array[current_slot][j] = -1;
                    fd_mapping.netfd_to_slot[current_slot][global_index] = -1;
                }
            }
        }
    }
}

// 示例使用
int main() {
    printf("161\n");
    LoopQueue_t *time_queue = createLoopQueue(TIME_OUT);
    time_queue=LoopQueueEpollInit();
    printf("164\n");
    // 模拟客户端连接
    int netfd1 = 4; // 假设的客户端fd
    handleNewClient(time_queue, netfd1);
    
    printf("169\n");
    // 查找这个netfd在二维数组中的位置
    int time_slot, slot_index;
    findPositionByNetfd(netfd1, &time_slot, &slot_index);
    
    printf("174\n");
    printf("netfd=%d 位于时间槽%d, 槽内位置%d\n", 
           netfd1, time_slot, slot_index);
    printf("验证: time_queue->array[%d][%d] = %d\n", 
           time_slot, slot_index, time_queue->array[time_slot][slot_index]);
    

    // ===== 测试用例2: 同一连接多次更新位置 =====
    printf("\n===== 测试用例2: 同一连接多次更新位置 =====\n");
    // 模拟时间流逝，更新netfd位置
    for (int i = 0; i < 5; i++) {
        // 模拟时间前进
        sleep(1);
        updateNetfdPosition(time_queue, netfd1);
        findPositionByNetfd(netfd1, &time_slot, &slot_index);
        printf("更新后 netfd=%d 位于时间槽%d, 槽内位置%d\n",
               netfd1, time_slot, slot_index);
    }

    // ===== 测试用例3: 多个连接测试 =====
    printf("\n===== 测试用例3: 多个连接测试 =====\n");
    for (int i = 0; i < 10; i++) {
        int new_netfd = 10 + i;
        handleNewClient(time_queue, new_netfd);
        findPositionByNetfd(new_netfd, &time_slot, &slot_index);
        printf("新连接 netfd=%d 位于时间槽%d, 槽内位置%d\n",
               new_netfd, time_slot, slot_index);
    }

    // ===== 测试用例4: 检查超时机制（模拟时间前进） =====
    printf("\n===== 测试用例4: 检查超时机制 =====\n");
    printf("模拟时间前进 %d 秒...\n", TIME_OUT);
    for (int i = 0; i < TIME_OUT; i++) {
        // 每次循环前进1秒
        sleep(1);
        // 更新所有连接的位置（实际应用中应该在定时器回调中执行）
        for (int j = 0; j < MAX_CONNECTION; j++) {
            if (fd_mapping.index_to_netfd[j] != -1) {
                updateNetfdPosition(time_queue, fd_mapping.index_to_netfd[j]);
            }
        }
        // 打印第一个连接的位置变化
        findPositionByNetfd(netfd1, &time_slot, &slot_index);
        printf("时间前进 %d 秒后, netfd=%d 位于时间槽%d\n",
               i+1, netfd1, time_slot);
    }

    // ===== 测试用例5: 检查最大连接数限制 =====
    printf("\n===== 测试用例5: 检查最大连接数限制 =====\n");
    printf("尝试创建 %d 个连接...\n", MAX_CONNECTION + 5);
    for (int i = 0; i < MAX_CONNECTION + 5; i++) {
        int test_netfd = 100 + i;
        int result = handleNewClient(time_queue, test_netfd);
        if (result == 0) {
            printf("成功添加连接 netfd=%d\n", test_netfd);
        } else {
            printf("添加连接 netfd=%d 失败（达到最大连接数）\n", test_netfd);
        }
    }

    // 清理资源
    destroyLoopQueue(time_queue);
    return 0;
    return 0;
}
